package br.com.daniele.services;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
import org.springframework.web.multipart.MultipartFile;

import br.com.daniele.bean.Det;
import br.com.daniele.bean.InfNFe;
import br.com.daniele.bean.NFe;
import br.com.daniele.bean.NfeProc;
import br.com.daniele.connection.ConnectionFactory;
import br.com.daniele.controller.UploadFile;
import br.com.daniele.repositorio.PdfRepositario;
import br.com.daniele.util.DeleteAllXml;
import br.com.daniele.util.ZipUtil;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.mapper.CannotResolveClassException;

@Service
public class PdfServices {
	
	@Autowired
	private PdfRepositario pdfRepositario;
	
	private String property = System.getProperty("user.dir");
	
	static final int TAMANHO_BUFFER = 4096; // 4kb
	
	public static int fileNumberVariable = 000;
	
	public void salvar(NfeProc nfeProc){

		try {
			pdfRepositario.salvar(nfeProc);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	
	private void validaNfeJaCadastradaESalva(ArrayList<NfeProc> listNfeProc) {

		for (NfeProc nfeProc : listNfeProc) {

			if (nfeProc != null) {

				InfNFe byIdentificador = pdfRepositario.findNfeByIdentificador(nfeProc.getNFe().getInfNFe().getID());

				if (byIdentificador == null) {
					salvar(nfeProc);
					exportaPdf(nfeProc.getNFe().getInfNFe().getID(), nfeProc);
				}else {
					exportaPdf(nfeProc.getNFe().getInfNFe().getID(), nfeProc);
				}

			}

		}

		compactaArquivos();

	}
	

	public List<NfeProc> listAll() {
		return pdfRepositario.listAll();
	}

	public static void main(String[] args) {
		
		String tel = "58080.00";
		
		String format2 = NumberFormat.getCurrencyInstance(new Locale("pt","BR")).format(Double.valueOf(tel));
		//String format = NumberFormat.get.format(Double.valueOf(tel));
		
		
		System.out.println(format2);
		
	}
	
	
	
	public void uploadXMLToParsePdf(UploadFile uploadFile, BindingResult result) throws CannotResolveClassException{

		InputStream inputStream = null;
		FileOutputStream fileOutputStream = null;

		List<MultipartFile> XMLFiles = (List<MultipartFile>)uploadFile.getFile();
		ArrayList<File> xmlFilesToParse = new ArrayList<File>();

		int read = 0;
		byte [] bytes = new byte[1024];

		for (MultipartFile mf : XMLFiles) {

			String filename = mf.getOriginalFilename();
			try {

				inputStream = mf.getInputStream();
				File xml = salvaArquivoNoDiretorio(filename);

				fileOutputStream = new FileOutputStream(xml);

				while ( (read = inputStream.read(bytes)) != -1 ) {
					fileOutputStream.write(bytes, 0, read);				
				}

				fileOutputStream.flush();
				fileOutputStream.close();

				xmlFilesToParse.add(xml);

			} catch (IOException e) {
				e.getMessage();
			}
		}
		
		parseXMLToObject(xmlFilesToParse);
		
	}


	private void compactaArquivos() {
		
		try {
			ZipUtil.compress(new File(defaultZipFileName()), new File(defaultZipFileName()+".zip"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}


	
	private void parseXMLToObject(List<File> xmlsUploaded) throws CannotResolveClassException{
		
		NfeProc nfeProc = null;
		ArrayList<NfeProc> nfeToSave = new ArrayList<NfeProc>();
		
		for (File file : xmlsUploaded) {


				XStream stream = new XStream(new DomDriver());
				stream.useAttributeFor(InfNFe.class, "Id");
				stream.useAttributeFor(Det.class, "nItem");
				stream.omitField(NFe.class, "Signature");
				stream.alias("nfeProc", NfeProc.class);
				stream.processAnnotations(InfNFe.class);
				stream.ignoreUnknownElements();

				nfeProc = (NfeProc) stream.fromXML(file);


			nfeToSave.add(nfeProc);	

			deleteXMLFile(file);
		}		
		
		validaNfeJaCadastradaESalva(nfeToSave);		
		
	}
	

	private void exportaPdf(String fileName, NfeProc nfeProc){

		try {

			Connection connection = new ConnectionFactory().getConnection();

			/*FileInputStream fileInputStream = new FileInputStream("/br/com/daniele/relatorio/layoutDanfe.jrxml");
			JasperCompileManager.compileReport(fileInputStream);*/
			
			Map<String, Object> parametros = new HashMap<String, Object>();
			
	
			
			parametros.put("kye_id_nf", nfeProc.getNFe().getInfNFe().getID());
			parametros.put("KEY_NFE", nfeProc.getNFe().getInfNFe().getID());

			URL resource = this.getClass().getResource("/br/com/daniele/relatorio/layoutDanfe.jasper");
			InputStream fileInputStream;
			fileInputStream = (InputStream) resource.getContent();
			
			JasperPrint print = JasperFillManager.fillReport(fileInputStream, parametros, connection);
			
			FileOutputStream fileOutputStream = new FileOutputStream( salvaArquivoNoDiretorio(fileName+".pdf") );
			
			JRExporter exporter = new JRPdfExporter();
			exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);
			exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, fileOutputStream);
			exporter.exportReport();
			
			fileOutputStream.flush();
			fileOutputStream.close();
			connection.close();
			
			
		} catch (JRException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}

	}


	private File salvaArquivoNoDiretorio(String fileName) {
		
		SimpleDateFormat sdf = new SimpleDateFormat("ddMMyy");
		String dataAtual = sdf.format(new Date());
		
		File dir = new File(property+File.separatorChar+dataAtual+fileNumberVariable);
		if (!dir.exists()) {
			dir.mkdir();
		}
		
		File newFile = null;
		
		try {

			newFile = new File(dir.getAbsolutePath()+"\\"+fileName);
			if (!newFile.exists()) {
				newFile.createNewFile();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return newFile;		
		
	}
	
	private void deleteXMLFile(File file) {
		
		new DeleteAllXml(file).deleteXMLFile();	
		
	}
	
	
	private String defaultZipFileName() {
		SimpleDateFormat sdf = new SimpleDateFormat("ddMMyy");
		String dataAtual = sdf.format(new Date());
		return property+File.separatorChar+dataAtual+fileNumberVariable;
	}
	
	
	/*private void compactador(String diretorioDeDestino) {

		int cont;
		byte[] dados = new byte[TAMANHO_BUFFER];
		
		BufferedInputStream origem = null;
		FileInputStream streamDeEntrada = null;
		FileOutputStream destino = null;
		ZipOutputStream saida = null;
		ZipEntry entry = null;               
		
		try {
			
			File file = new File("C:\\Users\\eduardo.pereira\\Downloads\\pdfs");
			file.setReadable(true, false);
			streamDeEntrada = new FileInputStream(file);
			destino = new FileOutputStream(new File(diretorioDeDestino));
			saida = new ZipOutputStream(new BufferedOutputStream(destino));
			
			origem = new BufferedInputStream(streamDeEntrada, TAMANHO_BUFFER);
			entry = new ZipEntry(file.getName());
			saida.putNextEntry(entry);

			while ((cont = origem.read(dados, 0, TAMANHO_BUFFER)) != -1) {
				saida.write(dados, 0, cont);
			}
			
			origem.close();
			saida.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}

		
	}*/
	

}

